package com.dc.aimc.common.service.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.Map;


/**
 * JWT token工具类
 */
@Log4j2
@Component
public class JwtUtil {

    /**
     * 密钥
     */
    private final static String SECRET = "aimc.com";

    /**
     * 签发token
     *
     * @param info       附带信息
     * @param expireDate 过期时间
     * @return token
     */
    public static String signToken(Map<String, ?> info, Date expireDate) {
        try {
            JWTCreator.Builder builder = JWT.create();
            // 添加附带信息
            builder.withPayload(info);
            // 添加过期时间
            builder.withExpiresAt(expireDate);
            // 签发token
            return builder.sign(Algorithm.HMAC256(SECRET));
        } catch (Exception e) {
            log.error("签发token异常: 附带信息: {}, 秘钥: {}, 过期时间: {} 异常信息: ", info, SECRET, expireDate, e);
        }
        return null;
    }

    /**
     * 校验token
     *
     * @param token  令牌
     * @return boolean
     */
    public static boolean verifyToken(String token) {
        try {
            // 获取算法
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            // 生成JWTVerifier
            JWTVerifier verifier = JWT.require(algorithm).build();
            // 验证token
            verifier.verify(token);
            return true;
        } catch (Exception e) {
            log.error("token验证异常: token: {}, 秘钥: {} 异常信息: ", token, SECRET, e);
        }
        return false;
    }

    /**
     * 从token中获得附带info，无需secret
     *
     * @param token 令牌
     * @return info
     */
    public static String getInfo(String token, String key) {
        try {
            return JWT.decode(token).getClaim(key).asString();
        } catch (Exception e) {
            log.error("解析token附带信息异常: token: {} key: {} 异常信息: ", token, key, e);
        }
        return null;
    }

    /**
     * 刷新token令牌
     *
     * @param oldToken   旧token令牌
     * @param expireDate 新的过期时间
     * @return 新token
     */
    public static String refreshToken(String oldToken, Date expireDate) {
        try {
            JWTCreator.Builder builder = JWT.create();
            DecodedJWT jwt = JWT.decode(oldToken);
            // 附带信息
            for (Map.Entry<String, Claim> entry : jwt.getClaims().entrySet()) {
                builder.withClaim(entry.getKey(), entry.getValue().toString());
            }
            // 过期时间
            builder.withExpiresAt(expireDate);
            return builder.sign(Algorithm.HMAC256(jwt.getAlgorithm()));
        } catch (Exception e) {
            log.error("刷新token异常: 旧token: {} 过期时间: {} ", oldToken, expireDate, e);
        }
        return null;
    }

}
